<?php

!defined('IN_HC') && exit('Misquoted');

/**
 * Simple template class
 */
class template
{

    var $tplname;
    var $tpldir;
    var $objdir;
    var $tplfile;
    var $objfile;
    var $vars = array();
    var $force = 0;
    var $var_regexp = "\@?\\\$[a-z_][\\\$\w]*(?:\[[\w\-\.\"\'\[\]\$]+\])*";
    var $vtag_regexp = "\<\?=(\@?\\\$[a-zA-Z_][\\\$\w]*(?:\[[\w\-\.\"\'\[\]\$]+\])*)\?\>";
    var $const_regexp = "\{([\w]+)\}";

    function template($tplname='default')
    {
        $this->tplname = ($tplname !== 'default' && is_dir(FILE . '/view/' . $tplname)) ? $tplname : 'default';
        $this->tpldir = FILE . 'data/view/' . $this->tplname;
        $this->objdir = FILE . 'data/view';
    }

    function assign($k, $v)
    {
        $this->vars[$k] = $v;
    }

    function display($file)
    {
        GLOBAL $starttime, $mquerynum;
        $mtime = explode(' ', microtime());
        $this->assign('runtime', number_format($mtime[1] + $mtime[0] - $starttime, 6));
        $this->assign('querynum', $mquerynum);
        extract($this->vars, EXTR_SKIP);
        if(file_exists($this->gettpl($file)))
            include $this->gettpl($file); else
            exit('未找到相应模板：' . $this->gettpl($file));
    }

    function gettpl($file)
    {
        if(substr($file, 0, 7) == "file://")
        {
            $ppos = strrpos($file, "/");
            $dir_name = explode('/', substr($file, 7));
            $this->tplfile = FILE . "/" . substr($file, 7) . '.html';
            $this->objfile = $this->objdir . '/' . $dir_name[1] . '_' . substr($file, $ppos + 1) . '.tpl.php';
        }
        else
        {
            if($this->tplname !== 'default' && is_file($this->tpldir . '/' . $file . '.html'))
            {
                $this->tplfile = $this->tpldir . '/' . $file . '.html';
                $this->objfile = $this->objdir . '/' . $this->tplname . "_" . $file . '.tpl.php';
            }
            else
            {
                $this->tplfile = FILE . '/view/default/' . $file . '.html';
                $this->objfile = $this->objdir . '/' . $file . '.tpl.php';
            }
        }
        if($this->force || @filemtime($this->objfile) < @filemtime($this->tplfile))
        {
            $this->complie();
        }
        return $this->objfile;
    }

    function complie()
    {
        $template = @file_get_contents($this->tplfile);
        $template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
        $template = preg_replace("/\{($this->var_regexp)\}/", "<?=\\1?>", $template);
        $template = preg_replace("/\{($this->const_regexp)\}/", "<?=\\1?>", $template);
        $template = preg_replace("/(?<!\<\?\=|\\\\)$this->var_regexp/", "<?=\\0?>", $template);
        $template = preg_replace("/\{\{eval (.*?)\}\}/ies", "\$this->stripvtag('<?php \\1?>')", $template);
        $template = preg_replace("/\{eval (.*?)\}/ies", "\$this->stripvtag('<?php \\1?>')", $template);
        $template = preg_replace("/\{for (.*?)\}/ies", "\$this->stripvtag('<?php for(\\1) {?>')", $template);
        $template = preg_replace("/\{elseif\s+(.+?)\}/ies", "\$this->stripvtag('<?php } elseif(\\1) { ?>')", $template);
        $template = preg_replace("/\{tag:([^\}]+?)\/\}/ies", "\$this->tag('\\1')", $template);
        for($i = 0; $i < 2; $i++)
        {
            $template = preg_replace("/\{tag:(.+?)\}(.+?)\{\/tag\}/ies", "\$this->tag('\\1', '\\2')", $template);
            $template = preg_replace("/\{loop\s+$this->vtag_regexp\s+$this->vtag_regexp\s+$this->vtag_regexp\}(.+?)\{\/loop\}/ies", "\$this->loopsection('\\1', '\\2', '\\3', '\\4')", $template);
            $template = preg_replace("/\{loop\s+$this->vtag_regexp\s+$this->vtag_regexp\}(.+?)\{\/loop\}/ies", "\$this->loopsection('\\1', '', '\\2', '\\3')", $template);
        }
        $template = preg_replace("/\{if\s+(.+?)\}/ies", "\$this->stripvtag('<?php if(\\1) { ?>')", $template);
        $template = preg_replace("/\{template\s+(\w+?)\}/is", "<?php include \$this->gettpl('\\1');?>", $template);
        $template = preg_replace("/\{template\s+(.+?)\}/ise", "\$this->stripvtag('<?php include \$this->gettpl(\\1); ?>')", $template);
        $template = preg_replace("/\{else\}/is", "<? } else { ?>", $template);
        $template = preg_replace("/\{\/if\}/is", "<? } ?>", $template);
        $template = preg_replace("/\{\/for\}/is", "<? } ?>", $template);
        $template = preg_replace("/$this->const_regexp/", "<?=\\1?>", $template);
        $template = "<?php if(!defined('IN_HC')) exit('Access Denied');?>\r\n$template";
        $template = preg_replace("/(\\\$[a-zA-Z_]\w+\[)([a-zA-Z_]\w+)\]/i", "\\1'\\2']", $template);
        $fp = fopen($this->objfile, 'w');
        fwrite($fp, $template);
        fclose($fp);
    }

    function stripvtag($s)
    {
        return preg_replace("/$this->vtag_regexp/is", "\\1", str_replace("\\\"", '"', $s));
    }

    function loopsection($arr, $k, $v, $statement)
    {
        $arr = $this->stripvtag($arr);
        $k = $this->stripvtag($k);
        $v = $this->stripvtag($v);
        $statement = str_replace("\\\"", '"', $statement);
        return $k ? "<?php foreach((array)$arr as $k=>$v) {?>$statement<?}?>" : "<? foreach((array)$arr as $v) {?>$statement<? } ?>";
    }

    function tag($taglist, $statement='')
    {
        $tag = preg_split("/\s+/", trim($taglist));
        $taglist = str_replace("'", "\'", $taglist);
        if('' != $statement)
        {
            $statement = str_replace("\\\"", '"', $statement);
            $statement = preg_replace_callback("/\[field:([^\]]+?)\/\]/is", array($this, 'callback'), $statement);
            return "<?php foreach((array)\$_ENV['tag']->$tag[0]('$taglist') as \$data) {?>$statement<? } ?>";
        }
        else
        {
            return "<?php echo \$_ENV['tag']->$tag[0]('$taglist');?>";
        }
    }

    function callback($matches)
    {
        $cmd = trim($matches[1]);
        $firstspace = strpos($cmd, ' ');
        if(!$firstspace)
        {
            return '<?php echo $data[' . $cmd . '];?>';
        }
        else
        {
            $field = substr($cmd, 0, $firstspace);
            $func = substr($cmd, $firstspace);
            return '<?php echo ' . str_replace('@me', '$data[' . $field . ']', $func) . " ?>";
        }
    }

}

?>